#include "InputMgr.h"
#include <GL/glew.h>
#include <GL/freeglut.h>

InputMgr* InputMgr::instance = 0;
std::list<KeyListener*> InputMgr::keyListeners;
std::list<MouseListener*> InputMgr::mouseListeners;
bool InputMgr::_bLMouseDown;

InputMgr::InputMgr() {
	_bLMouseDown = false;

	glutMouseFunc(sMouse);
	glutPassiveMotionFunc(sMotion);
	glutMouseWheelFunc(sMouseWheel);
	glutKeyboardFunc(sKeyDown);
	glutSpecialFunc(sSpecialDown);
	glutKeyboardUpFunc(sKeyUp);
	glutSpecialUpFunc(sSpecialUp);
}

InputMgr* InputMgr::getInstance() {
	if(instance == 0) {
		instance = new InputMgr();
	}
	return instance;
}

void InputMgr::registerListener(KeyListener* listener) {
	keyListeners.push_back(listener);
}

void InputMgr::registerListener(MouseListener* listener) {
	mouseListeners.push_back(listener);
}

void InputMgr::deleteListener(KeyListener* listener) {
	keyListeners.remove(listener);
}

void InputMgr::deleteListener(MouseListener* listener) {
	mouseListeners.remove(listener);
}

void InputMgr::sMouse(int button, int updown, int x, int y)
{
	if (updown)
	{
		if (button == 0)
			_bLMouseDown = false;

		std::list<MouseListener*>::iterator it = mouseListeners.begin();
		for( ; it != mouseListeners.end(); it++) {
			(*it)->OnMouseUp(button, x, y);
		}
	}
	else
	{
		if (button == 0)
			_bLMouseDown = true;
		std::list<MouseListener*>::iterator it = mouseListeners.begin();
		for( ; it != mouseListeners.end(); it++) {
			(*it)->OnMouseDown(button, x, y);
		}
	}
}

//-----------------------------------------------------------------------------

void InputMgr::sMotion(int x, int y)
{
	std::list<MouseListener*>::iterator it = mouseListeners.begin();
	for( ; it != mouseListeners.end(); it++) {
		if (_bLMouseDown) {
			(*it)->OnLeftMouseDrag(x, y);
		}
		(*it)->OnMouseMove(x, y);
	}
}

//-----------------------------------------------------------------------------

void InputMgr::sMouseWheel(int wheel_number, int direction, int x, int y)
{
	std::list<MouseListener*>::iterator it = mouseListeners.begin();
	for( ; it != mouseListeners.end(); it++) {
		(*it)->OnMouseWheel(wheel_number, direction, x, y);
	}
}

//-----------------------------------------------------------------------------

void InputMgr::sJoystick( unsigned int a, int b, int c, int d)
{
}

//-----------------------------------------------------------------------------

void InputMgr::sSpecialUp(int key, int x, int y)
{
	std::list<KeyListener*>::iterator it = keyListeners.begin();
	for( ; it != keyListeners.end(); it++) {
		(*it)->OnKeyUp(key, 0);
	}
}

//-----------------------------------------------------------------------------

void InputMgr::sKeyUp(unsigned char key, int x, int y)
{
	std::list<KeyListener*>::iterator it = keyListeners.begin();
		for( ; it != keyListeners.end(); it++) {
			(*it)->OnKeyUp(0, key);
		}
}

//-----------------------------------------------------------------------------

void InputMgr::sSpecialDown(int key, int x, int y)
{
	std::list<KeyListener*>::iterator it = keyListeners.begin();
	for( ; it != keyListeners.end(); it++) {
		(*it)->OnKeyDown(key, 0);
	}
}

//-----------------------------------------------------------------------------

void InputMgr::sKeyDown(unsigned char key, int x, int y)
{
	std::list<KeyListener*>::iterator it = keyListeners.begin();
	for( ; it != keyListeners.end(); it++) {
		(*it)->OnKeyDown(0, key);
	}
}
